from ctypes import *
import time

class Mem:
    def __init__(self,fn):
        self.fn  = fn
        self.lib = CDLL(fn)

        self.lib.writePoint.restype = c_uint64
        self.lib.appData.restype = c_void_p
        self.lib.attachMem.restype = c_void_p
        self.lib.getBuf.restype = c_void_p
        self.read_point = 0
        
    def dump(self):
        self.lib.dumpMem(c_void_p(self.h))

    def mmap(self,len,off):
        # print(" after now:{} off:{} len:{}".format(self.writePoint(),off,len))
        
        addr = self.lib.getBuf(c_void_p(self.h), c_uint64(off), c_int(len))
        vbuf = cast( addr, POINTER(c_ubyte*len) )
        return vbuf.contents

    def appData(self,types):
        addr = self.lib.appData(c_void_p(self.h))
        vbuf = cast( addr, POINTER(types) )
        return vbuf.contents
    
    def reset(self):
        self.lib.reset(c_void_p(self.h))
        self.rw_sync()

    def writePoint(self):
        return self.lib.writePoint(c_void_p(self.h))

    def setWritePoint(self,off):
        return self.lib.setWritePoint(c_void_p(self.h),c_uint64(off))

    def readRTL(self, l):
        r = self.mmap(l,self.read_point*2)
        self.read_point += l//2
        return r

    def rw_sync(self):
        self.read_point = int(self.writePoint())

    def readPoint(self):
        return self.read_point

    def left(self):
        return self.writePoint()-self.read_point

    def read(self,l):
        cnt=0
        while self.left()<l:
            time.sleep(0.01)
            cnt += 1
            if cnt>1000:
                print("time out, no packet recv",
                    self.writePoint(),
                    self.read_point)
                break
        return self.readRTL(l*2)



  
